
package ch.hearc.cryptologie.cryptographie.symetrique.flots.rc4;

public class RC4
	{
	
	private int[] S;
	private int[] K;
	static public final int DEFAULT_KEY_LENGTH = 256;
	
	public RC4(String strKey)
		{
		char[] tmp = strKey.toCharArray();
		K = new int[tmp.length];
		for(int i = 0; i < K.length; i++)
			{
			K[i] = tmp[i];
			}
		
		S = new int[DEFAULT_KEY_LENGTH];
		this.init();
		}
	
	public String crypt(String text)
		{
		return cryptDecrypt(text);
		}
	
	public String decrypt(String cryptedText)
		{
		return cryptDecrypt(cryptedText);
		}
	
	private String cryptDecrypt(String str)
		{
		int x = 0;
		int y = 0;

		StringBuilder O = new StringBuilder();
		for(char of : str.toCharArray())
			{
			x = (x + 1) % DEFAULT_KEY_LENGTH;
			y = (S[x] + y) % DEFAULT_KEY_LENGTH;
			swap(x, y);
			int oc = S[(S[x] + S[y]) % DEFAULT_KEY_LENGTH];
			O.append((char)((int)of ^ oc));
			}
		
		return O.toString();
		}
	
	private void init()
		{
		int j = 0;
		for(int i = 0; i < S.length; i++)
			{
			S[i] = i;
			}
		for(int i = 0; i < S.length; i++)
			{
			j = (j + S[i] + K[i % K.length]) % DEFAULT_KEY_LENGTH;
			swap(i, j);
			}
		}
	
	private void swap(int i, int j)
		{
		int temp = S[i];
		S[i] = S[j];
		S[j] = temp;
		}
	}
